package com.wyw.hemerocallis.service.impl;

import com.alibaba.fastjson.JSON;
import com.wyw.hemerocallis.account.AddressInfo;
import com.wyw.hemerocallis.common.TableId;
import com.wyw.hemerocallis.entity.HemerocallisAddress;
import com.wyw.hemerocallis.filter.AccessContext;
import com.wyw.hemerocallis.repository.HemerocallisAddressRepository;
import com.wyw.hemerocallis.service.IAddressService;
import com.wyw.hemerocallis.vo.LoginUserInfo;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 用户账户信息接口实现类
 *
 * @author Mr Wu    yewen.wu.china@gmail.com
 * <p>
 * Update History:
 * Author        Time            Content
 */
@Slf4j
@Service
@Transactional(rollbackFor = Exception.class)
@RequiredArgsConstructor
public class AddressServiceImpl implements IAddressService {
    private final HemerocallisAddressRepository addressRepository;

    /**
     * 存储多个地址信息
     * @param addressInfo
     * @return
     */
    @Override
    public TableId createAddressInfo(AddressInfo addressInfo) {
        // 不能直接从参数中获取用户的 id 信息,因为前面的过滤器已经做了判空操作，所以这里不再处理，当然也可以做是否一致的操作，看是否有必要
        LoginUserInfo loginUserInfo = AccessContext.getLoginInfo();

        // 将传递的参数转换成实体对象,记得加参数校验
        List<HemerocallisAddress> hemerocallisAddressList = addressInfo.getAddressItems().stream()
                .map(a -> HemerocallisAddress.to(loginUserInfo.getId(), a))
                .collect(Collectors.toList());

        // 保存到数据表并把返回记录的 id 给调用方
        List<HemerocallisAddress> savedRecords = addressRepository.saveAll(hemerocallisAddressList);
        List<Long> ids = savedRecords.stream()
                .map(HemerocallisAddress::getId)
                .collect(Collectors.toList());
        log.info("创建address信息: {}, {}", loginUserInfo.getId(),
                JSON.toJSONString(ids));//这里注意ids为null会使系统异常，但是这个是保存，如果保存不上，则也就是异常了

        return new TableId(
                ids.stream().map(TableId.Id::new).collect(Collectors.toList())
        );
    }

    @Override
    public AddressInfo getCurrentAddressInfo() {
        LoginUserInfo loginUserInfo = AccessContext.getLoginInfo();

        // 根据 userId 查询到用户的地址信息, 再实现转换
        List<HemerocallisAddress> hemerocallisAddressList = addressRepository.queryAllByUserId(
                loginUserInfo.getId()
        );
        List<AddressInfo.AddressItem> addressItems = hemerocallisAddressList.stream()
                .map(HemerocallisAddress::toAddressItem)
                .collect(Collectors.toList());

        return new AddressInfo(loginUserInfo.getId(), addressItems);
    }

    @Override
    public AddressInfo getAddressInfoById(Long id) {
        HemerocallisAddress hemerocallisAddress = addressRepository.findById(id).orElse(null);
        if (null == hemerocallisAddress) {
            throw new RuntimeException("address不存在");
        }

        return new AddressInfo(
                hemerocallisAddress.getUserId(),
                Collections.singletonList(hemerocallisAddress.toAddressItem())
        );
    }

    @Override
    public AddressInfo getAddressInfoByTableId(TableId tableId) {
        List<Long> ids = tableId.getIds().stream()
                .map(TableId.Id::getId).collect(Collectors.toList());
        log.info("通过主键ID获得地址信息: {}", JSON.toJSONString(ids));

        List<HemerocallisAddress> hemerocallisAddressList = addressRepository.findAllById(ids);
        if (CollectionUtils.isEmpty(hemerocallisAddressList)) {
            return new AddressInfo(-1L, Collections.emptyList());
        }

        List<AddressInfo.AddressItem> addressItems = hemerocallisAddressList.stream()
                .map(HemerocallisAddress::toAddressItem)
                .collect(Collectors.toList());

        return new AddressInfo(
                hemerocallisAddressList.get(0).getUserId(), addressItems
        );
    }
}
